#pragma once

struct Point3;

struct Vector3 {
    float x;
    float y;
    float z;

    float mPadding; // To ensure 4word alignment

    Vector3(const float x1 = 0.0f, 
        const float y1 = 0.0f, 
        const float z1 = 0.0f);

    // vector = to - from
    Vector3(const Point3& from, const Point3& to);

    void set(const float x1, const float y1, const float z1);

    // vec = to - from
    void set(const Point3& from, const Point3& to);

    void crossProduct(const Vector3& v1);

    void normalize();

    bool isZero() const;

    float length() const;

    float sqrLength() const;

    // Note: newLenght should not be negative
    void setLength(const float newLength);

    bool operator==(const Vector3& v) const;
    bool operator!=(const Vector3& v) const;

    Vector3& operator+=(const Vector3& v);
    Vector3& operator-=(const Vector3& v);

    // Translate a point operation
    Point3 operator+(const Point3& p) const;

    // Vector addition and subtraction
    Vector3 operator+(const Vector3& v) const;
    Vector3 operator-(const Vector3& v) const;

    // Scale operations
    Vector3& operator*=(const float s);
    Vector3 operator*(const float s) const;
};

float dotProduct(const Vector3& v1, const Vector3& v2);

// Note: out should be different than v1 and v2
void crossProduct(const Vector3& v1, const Vector3& v2, Vector3& out);

void normalize(const Vector3& v, Vector3& out);